package com.wb3.meta.api.core.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.wb3.meta.api.core.dao.*;
import com.wb3.meta.api.core.model.GoodsInfo;
import com.wb3.meta.api.core.model.MyToys;
import com.wb3.meta.api.core.model.Toys;
import com.wb3.meta.api.core.model.ToysChatMsgs;
import com.wb3.meta.api.core.service.*;
import com.wb3.meta.api.core.vo.*;
import com.wb3.meta.common.authentication.RequestHolder;
import com.wb3.meta.common.enums.EnumConstants;
import com.wb3.meta.common.pojo.ResultT;
import com.wb3.meta.common.utils.StringCommonUtils;
import com.wb3.meta.common.utils.TimeUtils;
import com.wb3.meta.common.utils.UploadFileUtils;
import com.wb3.meta.config.utils.BaichuanUtils;
import com.wb3.meta.config.utils.RedisUtils;
import com.wb3.meta.config.utils.TTSUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;

@Slf4j
@Service("myToysService")
@Transactional(transactionManager = "dataSourceTransactionManagerOne", rollbackFor = Exception.class)
public class MyToysServiceImpl implements MyToysService {

    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private MyToysMapper myToysMapper;

    @Autowired
    private CustomerToysMapper customerToysMapper;

    @Autowired
    private BaichuanUtils baichuanUtils;

    @Autowired
    private ToysChatMsgsService toysChatMsgsService;

    @Autowired
    private UserChatListMapper userChatListMapper;

    @Autowired
    private TTSUtils ttsUtils;

    @Autowired
    private UploadFileUtils uploadFileUtils;

    @Autowired
    private CustomerToysService customerToysService;

    @Autowired
    private ToysMapper toysMapper;

    @Lazy
    @Autowired
    private UsersService usersService;

    @Autowired
    private ToysChatMsgsMapper toysChatMsgsMapper;


    @Autowired
    private MpGetToysMapper mpGetToysMapper;

    @Autowired
    private GoodsInfoService goodsInfoService;


    /**
     * 分页查询方法
     *
     * @param vo
     * @return
     */
    @Override
    public Page<ResMyToysVo> getModelPage(ReqMyToysVo vo) {
        return null;
    }

    /**
     * 列表查询方法 -返回 res 对象
     *
     * @param vo
     * @return
     */
    @Override
    public List<ResMyToysVo> getModelListByConditions(ReqMyToysVo vo) {
        return myToysMapper.getModelListByConditions(vo);
    }

    /**
     * 根据条件查询单条数据方法，返回res vo类
     *
     * @param vo
     * @return
     */
    @Override
    public ResMyToysVo getResModelByConditions(ReqMyToysVo vo) {
        return myToysMapper.getResModelByConditions(vo);
    }

    /**
     * 根据条件查询单个对象方法
     *
     * @param myToys
     * @return
     */
    @Override
    public MyToys getModelByConditions(MyToys myToys) {
        return null;
    }

    /**
     * 根据id查询单个对象方法
     *
     * @param id
     * @return
     */
    @Override
    public MyToys getModelById(Object id) {
        return myToysMapper.selectByPrimaryKey(id);
    }

    /**
     * 新增对象方法
     *
     * @param myToys
     */
    @Override
    public void addModel(MyToys myToys) {
        myToys.setCreateTime(new Date());
        myToys.setStatus(EnumConstants.StatusEnum.VALID.getCode());
        myToys.setUserId(myToys.getUserId() != null ? myToys.getUserId() : RequestHolder.getUserId());
        myToysMapper.insertUseGeneratedKeys(myToys);
    }

    /**
     * 更新对象方法
     *
     * @param myToys
     */
    @Override
    public void updateModel(MyToys myToys) {
        myToys.setUpdateTime(new Date());
        myToysMapper.updateByPrimaryKeySelective(myToys);
    }

    /**
     * 根据id删除对象方法
     *
     * @param id
     */
    @Override
    public void deleteModelById(Object id) {

    }

    /**
     * 获取分页数据，返回 map对象方法
     *
     * @param vo
     * @return
     */
    @Override
    public ResultT getModelMapPage(ReqMyToysVo vo) {
        return null;
    }

    /**
     * 根据id查询单个对象方法，返回 map对象方法
     *
     * @param id
     * @return
     */
    @Override
    public ResultT getModelMapById(Object id) {
        return null;
    }

    /**
     * 根据条件查询单个对象，返回map对象方法
     *
     * @param myToys
     * @return
     */
    @Override
    public ResultT getModelMapByConditions(MyToys myToys) {
        return null;
    }

    /**
     * 查询列表-map对象
     *
     * @param vo
     * @return
     */
    @Override
    public ResultT getResModelListMapByConditions(ReqMyToysVo vo) {
        return ResultT.success(myToysMapper.getModelListByConditions(vo));
    }

    /**
     * 根据条件查询res vo对象，返回map对象方法
     *
     * @param vo
     * @return
     */
    @Override
    public ResultT getResModelMapByConditions(ReqMyToysVo vo) {
        return ResultT.success(myToysMapper.getResModelByConditions(vo));
    }

    /**
     * 更新或插入对象方法
     *
     * @param vo
     * @return
     */
    @Override
    public ResultT saveOrUpdate(ReqMyToysVo vo) {
        if (vo.getId() != null) {
            updateModel(vo);
        } else {
            addModel(vo);
        }
        return ResultT.success(vo);
    }

    /**
     * 根据条件删除方法
     *
     * @param vo
     * @return
     */
    @Override
    public ResultT delete(ReqMyToysVo vo) {
        return null;
    }


    /**
     * @param vo
     * @return com.wb3.meta.common.pojo.ResultT
     * @Author RP
     * @Description //TODO 绑定崽崽
     * @Date 13:56 2024/1/11
     * @Param [vo]
     */
    @Override
    public ResultT bindToy(ReqMyToysVo vo) {
        if (StringUtils.isBlank(vo.getIdentityId())) {
            return ResultT.fail("崽崽数字码不能为空");
        }
        ReqCustomerToysVo customerToysVo = new ReqCustomerToysVo();
        customerToysVo.setIdentityId(vo.getIdentityId());
        customerToysVo.setStatus(0);
        ResCustomerToysVo resCustomerToysVo = customerToysMapper.getResModelByConditions(customerToysVo);
        if (resCustomerToysVo == null) {
            return ResultT.fail("崽崽数字码不存在，无法绑定");
        }
        ResMyToysVo resMyToysVo = myToysMapper.getResModelByConditions(vo);
        if (resMyToysVo != null) {
            return ResultT.fail("崽崽数字码已被绑定");
        }
        vo.setUserId(RequestHolder.getUserId());
        vo.setNickName(resCustomerToysVo.getName());
        vo.setPic(resCustomerToysVo.getPic());
        vo.setPersonality(resCustomerToysVo.getPersonality());
        vo.setBirthday(resCustomerToysVo.getBirthday());
        saveOrUpdate(vo);
        return ResultT.success();
    }

    @Override
    public ResultT chat(ReqMyToysVo reqMyToysVo) throws IOException {
        if (reqMyToysVo.getUserChatListId() == null) {
            return ResultT.fail("未找到对话信息");
        }
        if (reqMyToysVo.getId() == null) {
            return ResultT.fail("崽崽id不能为空");
        }
        if (StringUtils.isBlank(reqMyToysVo.getContent())) {
            return ResultT.fail("聊天内容不能为空");
        }
        reqMyToysVo.setUserId(RequestHolder.getUserId());
        ResMyToysVo resMyToysVo = getResModelByConditions(reqMyToysVo);
        if (resMyToysVo == null) {
            return ResultT.fail("未查询到数据");
        }
        if (resMyToysVo.getStatus() == 1) {
            return ResultT.fail("崽崽已过期");
        }
        if (resMyToysVo.getPower() < 3) {
            return ResultT.fail("崽崽体力不足");
        }

        if (resMyToysVo.getTextChatId() == null) {
            return ResultT.fail("未配置角色模型");
        }
        if (reqMyToysVo.isAudio()) {
            if (StringUtils.isBlank(resMyToysVo.getAudioChatId())) {
                return ResultT.fail("未配置语音模型");
            }
        }


        ReqUserChatListVo reqUserChatListVo = new ReqUserChatListVo();
        reqUserChatListVo.setUserId(RequestHolder.getUserId());
        reqUserChatListVo.setMyToysId(reqMyToysVo.getId());

        ResUserChatListVo resUserChatListVo = userChatListMapper.getResModelByConditions(reqUserChatListVo);
        if (resUserChatListVo == null) {
            return ResultT.fail("对话不存在");
        }


        //当日文字聊天次数
//        String textKey = "todayTextChatCount" + "-" + reqMyToysVo.getId() + "-" + RequestHolder.getUserId();
//        Integer todayTextChatCount = (Integer) redisUtils.get(textKey);
//        String shareKey = "todayShare"  + "-" + reqMyToysVo.getId() + "-" +  RequestHolder.getUserId();
//        Boolean todayShare = redisUtils.get(shareKey) != null ?  (Boolean)redisUtils.get(shareKey) : false ;
//        if (todayTextChatCount != null) {
//            if (todayTextChatCount >= resMyToysVo.getTextChatLimit()) {
//                //当日没有分享，聊天超过上限
//                if (!todayShare) {
//                    return ResultT.fail("今日聊天已达上限，分享聊天记录可获得聊天句数哦");
//                }
//                //当日分享，增加20条上限， 目前已经超过最高上限
//                if(todayTextChatCount >= resMyToysVo.getTextChatLimit() + 20){
//                    return ResultT.fail("今日聊天已达上限");
//                }
//            }
//        }


        ReqToysChatMsgsVo reqToysChatMsgsVo = new ReqToysChatMsgsVo();
        reqToysChatMsgsVo.setUserChatListId(reqMyToysVo.getUserChatListId());
        reqToysChatMsgsVo.setUserTextContent(reqMyToysVo.getContent());
        reqToysChatMsgsVo.setUserId(RequestHolder.getUserId());
        reqToysChatMsgsVo.setLimitCount(20); //取最新10条聊天记录
        List<ResToysChatMsgsVo> resToysChatMsgsVos = toysChatMsgsService.getModelListByConditions(reqToysChatMsgsVo);
        List<BaichuanUtils.Message> historyChatList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(resToysChatMsgsVos)) {
            for (int i = resToysChatMsgsVos.size() - 1; i >= 0; i--) {
                ResToysChatMsgsVo chatMsgsVo = resToysChatMsgsVos.get(i);
                if (StringUtils.isNotBlank(chatMsgsVo.getUserTextContent())) {
                    historyChatList.add(new BaichuanUtils.Message("user", chatMsgsVo.getUserTextContent()));
                }
                if (StringUtils.isNotBlank(chatMsgsVo.getToysTextContent())) {
                    historyChatList.add(new BaichuanUtils.Message("assistant", chatMsgsVo.getToysTextContent()));
                }
            }
        }
        historyChatList.add(new BaichuanUtils.Message("user", reqMyToysVo.getContent()));

        Map<String, String> result = baichuanUtils.getChatInfo(resMyToysVo.getTextChatId(), historyChatList);
        log.info("百川返回信息：{}", result);
        if (result.isEmpty()) {
            return ResultT.fail("调用角色接口失败");
        }
        if ("200".equals(result.get("code"))) {
            JSONObject jb = JSONObject.parseObject(result.get("result"));
            JSONArray msgs = jb.getJSONArray("choices");
            String resContent = msgs.getJSONObject(0).getJSONObject("message").getString("content");
            reqToysChatMsgsVo.setToysTextContent(resContent);

            //转tts
            if (reqMyToysVo.isAudio()) {
                try {
                    TTSUtils.ResponseInfo ttsResponse = ttsUtils.testToTTS(StringCommonUtils.removeBrackets(resContent), resMyToysVo.getAudioChatId());
                    //tts转换成功
                    if (ttsResponse.getAudioFile() != null) {
                        ResultT uploadRes = uploadFileUtils.uploadFileToAliyun("user/chat/audio",
                                System.currentTimeMillis() + "-" + reqMyToysVo.getId() + "-" + RequestHolder.getUserId() + ".mp3",
                                ttsResponse.getAudioFile());
                        reqMyToysVo.setToyChatAudioUrl(uploadRes.getCode() == 1 ? uploadRes.getData().toString() : "");
                        reqMyToysVo.setAudioDuration(ttsResponse.getDuration());
                        reqToysChatMsgsVo.setToysAudioContent(uploadRes.getCode() == 1 ? uploadRes.getData().toString() : "");
                        reqToysChatMsgsVo.setAudioDuration(ttsResponse.getDuration());
                        //删除源文件
                        if (!ttsResponse.getAudioFile().delete()) {
                            // Handle the case where deletion failed
                            log.warn("Failed to delete file: {}", ttsResponse.getAudioFile().getAbsolutePath());
                        }
                    } else {
                        log.error("用户：{}  --tts-文字：{}  转换失败，错误原因：{}",
                                RequestHolder.getUserId(), reqMyToysVo.getContent(), "调用tts接口 500");
                    }
                } catch (Exception e) {
                    reqToysChatMsgsVo.setToysAudioContent("error");
                    log.error("用户：{}  --tts-文字：{}  转换失败，错误原因：{}",
                            RequestHolder.getUserId(), reqMyToysVo.getContent(), e.getMessage());
                    return ResultT.fail("文字转语音失败");
                }
            }
            reqMyToysVo.setToyChatMsg(resContent);
            reqMyToysVo.setPower(resMyToysVo.getPower() - 3);  //聊天 每次消耗3体力
            //超100 不加心情
            if (resMyToysVo.getMood() < 100) {
                reqMyToysVo.setMood(resMyToysVo.getMood() + 1); //聊天心情+1；
            }
            reqMyToysVo.setIntimacy(resMyToysVo.getIntimacy() + calIntimacy(resMyToysVo, reqMyToysVo.getMood()));

            saveOrUpdate(reqMyToysVo);
            toysChatMsgsService.saveOrUpdate(reqToysChatMsgsVo);

//            if (todayTextChatCount != null) {
//                redisUtils.set(textKey,++todayTextChatCount,TimeUtils.calculateRemainingSecondsUntilMidnight());
//            }else{
//                redisUtils.set(textKey,1, TimeUtils.calculateRemainingSecondsUntilMidnight());
//            }
            boolean isGive = addToys(resMyToysVo, resContent); //大姨破防添加莉莉
            reqMyToysVo.setCode(isGive ? 1 : 0);
            return ResultT.success(reqMyToysVo);
        } else {
            return ResultT.fail("出错了，请稍后重试");
        }


    }
    @Override
    public int calIntimacy(ResMyToysVo resMyToysVo, int mood) {
        String key = "dayMoodCount:" + resMyToysVo.getId() + "-" + RequestHolder.getUserId();

        if (90 > mood && mood >= 80) {
            key+="-one";
            boolean countLevelOne = redisUtils.get(key) != null && (boolean) redisUtils.get(key);
            if(countLevelOne){
                return 0;
            }
            redisUtils.set(key, true, 24 * 60 * 60);
            return 1;
        } else if (100 > mood && mood >= 90) {
            key+="-two";
            boolean countLevelTwo = redisUtils.get(key) != null && (boolean) redisUtils.get(key);
            if(countLevelTwo){
                return 0;
            }
            redisUtils.set(key, true, 24 * 60 * 60);
            return 2;
        } else if (mood == 100) {
            key+="-three";
            boolean countLevelThree = redisUtils.get(key) != null && (boolean) redisUtils.get(key);
            if (countLevelThree) {
                return 0;
            }
            redisUtils.set(key, true, 24 * 60 * 60);
            return 3;
        }
        return 0;
    }
//    private boolean checkCanChat(ResMyToysVo resMyToysVo){
//
//    }

    private boolean addToys(ResMyToysVo resMyToysVo, String chatMsg) {
        int toysId = 9; // 本次活动送的是塞西
        //老板破防，查询用户是否已经拥有崽崽
        if (resMyToysVo.getToysId() == 11 && StringUtils.isNotBlank(chatMsg) && chatMsg.contains("破防")) {
            ReqMyToysVo reqMyToysVo = new ReqMyToysVo();
            reqMyToysVo.setUserId(RequestHolder.getUserId());
            reqMyToysVo.setToysId(toysId);

            List<ResMyToysVo> myToysVoList = getModelListByConditions(reqMyToysVo);
            if (!CollectionUtils.isEmpty(myToysVoList)) {
                log.info("用户：{}，已经获取过，不再发放新的崽崽", RequestHolder.getUserId());
                return false;
            }
            //发放崽崽
            createMyToys(RequestHolder.getUserId(), toysId, null);
            return true;
        }
        return false;
    }


    @Override
    public ResultT text2Audio(ReqMyToysVo reqMyToysVo) {
        if (reqMyToysVo.getToysChatMsgsId() == null) {
            return ResultT.fail("聊天id不能为空");
        }
        if (reqMyToysVo.getMyToysId() == null) {
            return ResultT.fail("崽崽id不能为空");
        }
        ReqToysChatMsgsVo reqToysChatMsgsVo = new ReqToysChatMsgsVo();
        reqToysChatMsgsVo.setId(reqMyToysVo.getToysChatMsgsId());
        reqToysChatMsgsVo.setMyToysId(reqMyToysVo.getMyToysId());
        ResToysChatMsgsVo resToysChatMsgsVo = toysChatMsgsService.getResModelByConditions(reqToysChatMsgsVo);
        if (resToysChatMsgsVo == null) {
            return ResultT.fail("聊天记录不存在");
        }
        if (StringUtils.isNotBlank(resToysChatMsgsVo.getToysAudioContent())) {
            return ResultT.success(resToysChatMsgsVo);
        }
        try {
            TTSUtils.ResponseInfo ttsResponse = ttsUtils.testToTTS(StringCommonUtils.removeBrackets(resToysChatMsgsVo.getToysTextContent()), resToysChatMsgsVo.getAudioChatId());
            ResultT uploadRes = uploadFileUtils.uploadFileToAliyun("user/chat/audio",
                    System.currentTimeMillis() + "-" + reqMyToysVo.getId() + "-" + RequestHolder.getUserId() + ".mp3",
                    ttsResponse.getAudioFile());
            resToysChatMsgsVo.setToysAudioContent(uploadRes.getCode() == 1 ? uploadRes.getData().toString() : "");
            resToysChatMsgsVo.setAudioDuration(ttsResponse.getDuration());
            toysChatMsgsService.updateModel(resToysChatMsgsVo);
        } catch (Exception e) {
            log.error("用户：{}tts-文字：{}  转换失败，错误原因：{}",
                    RequestHolder.getUserId(), reqMyToysVo.getContent(), e.getMessage());
            return ResultT.fail("文字转化语音失败");
        }
        return ResultT.success(resToysChatMsgsVo);
    }

    @Override
    public ResultT shareMsg(ReqMyToysVo reqMyToysVo) {
        if (reqMyToysVo.getId() == null) {
            return ResultT.fail("崽崽id不能为空");
        }
        String shareKey = "todayShare" + "-" + reqMyToysVo.getId() + "-" + RequestHolder.getUserId();
//        log.info("-TimeUtils.getNowDayZeroSecond()-------{}",TimeUtils.calculateRemainingSecondsUntilMidnight());
        Boolean todayShare = redisUtils.get(shareKey) != null ? (Boolean) redisUtils.get(shareKey) : false;
        if (todayShare) {
            return ResultT.success("today_used");  //今日已经分享过了
        }
        redisUtils.set(shareKey, true, TimeUtils.calculateRemainingSecondsUntilMidnight());
        return ResultT.success();
    }

    @Override
    public void giveToys(ReqUsersVo reqUsersVo) {
        Integer userId = reqUsersVo.getId();
//        log.info("userId ======== {}",userId);
        LocalDateTime dateTime = LocalDateTime.of(2024, Month.MARCH, 31, 23, 59, 59);
        // 使用带时区的 ZonedDateTime
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime = dateTime.atZone(zoneId);

        // 将 ZonedDateTime 转换为 Date 对象
        Date date = Date.from(zonedDateTime.toInstant());

        //发放榴莲同学
        createMyToys(userId, 3, null);

        //发放老板
//        createMyToys(userId, 11, date);

        //发放lili
        createMyToys(userId, 2, null);

    }

    private void createMyToys(Integer userId, Integer toysId, Date expireTime) {
        //创建榴莲同学 唯一码
//        ReqCustomerToysVo reqCustomerToysVo = new ReqCustomerToysVo();
//        reqCustomerToysVo.setIdentityId(StringCommonUtils.generateUniqueCode());
//        reqCustomerToysVo.setToysId(toysId);
//        customerToysService.saveOrUpdate(reqCustomerToysVo);
        String identityId = createCustomerToy(toysId);
        Toys toys = toysMapper.selectByPrimaryKey(toysId);  //查询崽崽信息
        MyToys myToys = new MyToys();
        BeanUtils.copyProperties(toys, myToys); //复制信息
        myToys.setUserId(userId);
        myToys.setNickName(toys.getName());
        myToys.setIdentityId(identityId);
        myToys.setExpireTime(expireTime);

        addModel(myToys);

    }

    private String createCustomerToy(Integer toysId) {
        ReqCustomerToysVo reqCustomerToysVo = new ReqCustomerToysVo();
        reqCustomerToysVo.setIdentityId(StringCommonUtils.generateUniqueCode());
        reqCustomerToysVo.setToysId(toysId);
        customerToysService.saveOrUpdate(reqCustomerToysVo);
        return reqCustomerToysVo.getIdentityId();
    }

    @Override
    public ResultT testGive() {
        ReqUsersVo reqUsersVo = new ReqUsersVo();
        reqUsersVo.setOpenId("_----");
        usersService.saveOrUpdate(reqUsersVo);

        //新增逻辑，给用户发放一个大姨/榴莲同学，有效期到2024-2-29
        giveToys(reqUsersVo);
        return ResultT.success();
    }

    @Override
    public ResultT resetChatMsg(ReqMyToysVo reqMyToysVo) {
        if (reqMyToysVo.getId() == null) {
            return ResultT.fail("崽崽id不能为空");
        }
        reqMyToysVo.setUserId(RequestHolder.getUserId());
        ResMyToysVo resMyToysVo = getResModelByConditions(reqMyToysVo);
        if (resMyToysVo == null) {
            return ResultT.fail("崽崽信息不存在");
        }
        if (resMyToysVo.getUserChatListId() == null) {
            return ResultT.fail("未查询到崽崽聊天记录");
        }
        ToysChatMsgs tc = new ToysChatMsgs();
        tc.setUserChatListId(resMyToysVo.getUserChatListId());
        toysChatMsgsMapper.delete(tc);

        //大姨，需要手动插入一条
        if (resMyToysVo.getToysId() == 11) {
            ReqToysChatMsgsVo reqToysChatMsgsVo = new ReqToysChatMsgsVo();
            reqToysChatMsgsVo.setMyToysId(reqMyToysVo.getId());
            reqToysChatMsgsVo.setUserChatListId(resMyToysVo.getUserChatListId());
            reqToysChatMsgsVo.setToysTextContent("（斜眼看）最近工作怎么样呀？");
            toysChatMsgsService.saveOrUpdate(reqToysChatMsgsVo);
        }

        return ResultT.success();
    }

    @Override
    public ResultT batchSend(ReqMyToysVo reqMyToysVo) {
        LocalDateTime dateTime = LocalDateTime.of(2024, Month.MARCH, 31, 23, 59, 59);
        // 使用带时区的 ZonedDateTime
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime = dateTime.atZone(zoneId);

        // 将 ZonedDateTime 转换为 Date 对象
        Date date = Date.from(zonedDateTime.toInstant());
        List<ResUsersVo> usersVoList = usersService.getModelListByConditions(new ReqUsersVo());
        usersVoList.forEach(resUsersVo -> {
            createMyToys(resUsersVo.getId(), 11, date);
        });
        return ResultT.success();
    }

    /**
     * @param msg
     * @return java.lang.String
     * @Author RP
     * @Description //TODO 公众号领取娃娃
     * @Date 22:46 2024/2/8
     * @Param [msg]
     */
    @Override
    public String getWawaByMp(String mpOpenId, String msg) {
        Integer number = null;
        try {
            number = Integer.parseInt(msg);
        } catch (Exception e) {
            log.error("发送的消息非数字");
            return "请您输入正确的数字编号";
        }
        //领取崽崽
        if (0 < number && number < 8) {
            ReqMpGetToysVo reqMpGetToysVo = new ReqMpGetToysVo();
            //这里做转换
            if (number == 6) {
                number = 10;
            } else if (number == 7) {
                number = 12;
            }
            reqMpGetToysVo.setMpOpenId(mpOpenId);
            List<ResMpGetToysVo> mpGetToysVoList = mpGetToysMapper.getModelListByConditions(reqMpGetToysVo);
            if (!CollectionUtils.isEmpty(mpGetToysVoList)) {
                log.info("用户：{}，已经领取过崽崽", mpOpenId);
                return "每人限领1只哦，点击「领取福利」，完成任务可领养更多崽崽！";
            }
            String identityId = createCustomerToy(number);
            reqMpGetToysVo.setToysId(number);
            reqMpGetToysVo.setIdentityId(identityId);
            mpGetToysMapper.insert(reqMpGetToysVo);
            return "恭喜您成功获得一只崽崽！\n崽崽数字码：" + identityId + "\n点击菜单“去找崽崽”绑定吧！";
        }
        return "请您输入正确的数字编号";
    }

    @Override
    public ResultT textToTts(ReqMyToysVo reqMyToysVo) {
        if (StringUtils.isBlank(reqMyToysVo.getContent())) {
            return ResultT.fail("文本不能为空");
        }
        if (StringUtils.isBlank(reqMyToysVo.getAudioId())) {
            return ResultT.fail("语音模型id不能为空");
        }
        try {
            TTSUtils.ResponseInfo ttsResponse = ttsUtils.testToTTS(StringCommonUtils.removeBrackets(reqMyToysVo.getContent()), reqMyToysVo.getAudioId() + "");
            //tts转换成功
            if (ttsResponse.getAudioFile() != null) {
                ResultT uploadRes = uploadFileUtils.uploadFileToAliyun("common/tts/audio",
                        System.currentTimeMillis() + "-" + reqMyToysVo.getId() + "-" + RequestHolder.getUserId() + ".mp3",
                        ttsResponse.getAudioFile());
                //删除源文件
                if (!ttsResponse.getAudioFile().delete()) {
                    // Handle the case where deletion failed
                    log.warn("Failed to delete file: {}", ttsResponse.getAudioFile().getAbsolutePath());
                }
                return ResultT.success(uploadRes.getCode() == 1 ? uploadRes.getData().toString() : "");
            } else {
                log.error("tts-文字：{}  转换失败，错误原因：{}",
                        reqMyToysVo.getContent(), "调用tts接口 500");
                return ResultT.fail("调用tts接口 500");
            }
        } catch (Exception e) {
            log.error("tts-文字：{}  转换失败，错误原因：{}",
                    reqMyToysVo.getContent(), e.getMessage());
            return ResultT.fail("文字转语音失败");
        }

    }

    @Override
    public ResultT createStory(ReqMyToysVo reqMyToysVo) {
        if (reqMyToysVo.getUserChatListId() == null) {
            return ResultT.fail("对话id不能为空");
        }
        if (reqMyToysVo.getId() == null) {
            return ResultT.fail("崽崽id不能为空");
        }
        reqMyToysVo.setUserId(RequestHolder.getUserId());
        ResMyToysVo resMyToysVo = getResModelByConditions(reqMyToysVo);
        if (resMyToysVo == null) {
            return ResultT.fail("未查询到数据");
        }
        if (resMyToysVo.getStatus() == 1) {
            return ResultT.fail("崽崽已过期");
        }
        if (resMyToysVo.getTextChatId() == null) {
            return ResultT.fail("未配置角色模型");
        }


        ReqUserChatListVo reqUserChatListVo = new ReqUserChatListVo();
        reqUserChatListVo.setUserId(RequestHolder.getUserId());
        reqUserChatListVo.setMyToysId(reqMyToysVo.getId());

        ResUserChatListVo resUserChatListVo = userChatListMapper.getResModelByConditions(reqUserChatListVo);
        if (resUserChatListVo == null) {
            return ResultT.fail("对话不存在");
        }

        //当日文字聊天次数
        String textKey = "todayTextChatCount" + "-" + reqMyToysVo.getId() + "-" + RequestHolder.getUserId();
        Integer todayTextChatCount = (Integer) redisUtils.get(textKey);
        String shareKey = "todayShare" + "-" + reqMyToysVo.getId() + "-" + RequestHolder.getUserId();
        Boolean todayShare = redisUtils.get(shareKey) != null ? (Boolean) redisUtils.get(shareKey) : false;
        if (todayTextChatCount != null) {
            if (todayTextChatCount >= resMyToysVo.getTextChatLimit()) {
                //当日没有分享，聊天超过上限
                if (!todayShare) {
//                    reqMyToysVo.setCode(1001);
                    return ResultT.fail("今日聊天已达上限，分享聊天记录可获得聊天句数哦");
//                    return ResultT.success(reqMyToysVo);
                }
                //当日分享，增加20条上限， 目前已经超过最高上限
                if (todayTextChatCount >= resMyToysVo.getTextChatLimit() + 20) {
//                    reqMyToysVo.setCode(1002);
                    return ResultT.fail("今日聊天已达上限");
//                    return ResultT.success(reqMyToysVo);
                }
            }
        }
        String text = "以第一人称讲述一个符合你角色设定的有趣故事，故事要体现你和角色的反差感，100字以内";
        List<BaichuanUtils.Message> historyChatList = new ArrayList<>();
        historyChatList.add(new BaichuanUtils.Message("user", text));

        Map<String, String> result = baichuanUtils.getChatInfo(resMyToysVo.getTextChatId(), historyChatList);
        log.info("百川返回信息：{}", result);
        if (result.isEmpty()) {
            return ResultT.fail("调用角色接口失败");
        }
        if ("200".equals(result.get("code"))) {
            JSONObject jb = JSONObject.parseObject(result.get("result"));
            JSONArray msgs = jb.getJSONArray("choices");
            String resContent = msgs.getJSONObject(0).getJSONObject("message").getString("content");
            ReqToysChatMsgsVo reqToysChatMsgsVo = new ReqToysChatMsgsVo();
            reqToysChatMsgsVo.setUserChatListId(reqMyToysVo.getUserChatListId());
            reqToysChatMsgsVo.setUserId(RequestHolder.getUserId());
            reqToysChatMsgsVo.setToysTextContent(resContent);
            reqMyToysVo.setToyChatMsg(resContent);
            toysChatMsgsService.saveOrUpdate(reqToysChatMsgsVo);

            if (todayTextChatCount != null) {
                redisUtils.set(textKey, ++todayTextChatCount, TimeUtils.calculateRemainingSecondsUntilMidnight());
            } else {
                redisUtils.set(textKey, 1, TimeUtils.calculateRemainingSecondsUntilMidnight());
            }
            return ResultT.success(reqMyToysVo);
        } else {
            return ResultT.fail("出错了，请稍后重试");
        }

    }

    /**
     * @return void
     * @Author RP
     * @Description //处理崽崽购买事件
     * @Date 18:32 2024/3/30
     * @Param [goodsId]
     */
    @Override
    public void handleBuyToys(ResGoodsOrdersVo resGoodsOrdersVo) {
        GoodsInfo goodsInfo = goodsInfoService.getModelById(resGoodsOrdersVo.getGoodsId());
        if (goodsInfo == null) {
            log.error("商品：{}，未查询到信息", resGoodsOrdersVo.getGoodsId());
            return;
        }
        if (goodsInfo.getToysId() == null) {
            log.error("商品：{}，未配置崽崽信息，请核实", resGoodsOrdersVo.getGoodsId());
            return;
        }
        Toys toys = toysMapper.selectByPrimaryKey(goodsInfo.getToysId());
        if (resGoodsOrdersVo.getOrderType() == 0) {
            if (goodsInfo.getToyValidDays() == null) {
                createMyToys(resGoodsOrdersVo.getUserId(), toys.getId(), null);
            } else {
                // 获取当前时间
                ZonedDateTime now = ZonedDateTime.now();
                // 增加指定天数
                ZonedDateTime futureDate = now.plusDays(goodsInfo.getToyValidDays());

                // 将 ZonedDateTime 转换为 Date 对象
                Date date = Date.from(futureDate.toInstant());
                createMyToys(resGoodsOrdersVo.getUserId(), toys.getId(), date);
            }
            log.info("用户：{}，新增崽崽：{}，有效期{}", resGoodsOrdersVo.getUserId(), toys.getId(), goodsInfo.getToyValidDays() == null ? "无限制" : goodsInfo.getToyValidDays());
            return;
        }
        //续费

        ReqMyToysVo reqMyToysVo = new ReqMyToysVo();
        reqMyToysVo.setId(resGoodsOrdersVo.getMyToysId());
        ResMyToysVo resMyToysVo = getResModelByConditions(reqMyToysVo);
        if (resMyToysVo == null) {
            log.error("商品：{}，我的崽崽：{}未找到", resGoodsOrdersVo.getGoodsId(), resGoodsOrdersVo.getMyToysId());
            return;
        }
        BeanUtils.copyProperties(resMyToysVo, reqMyToysVo);
        reqMyToysVo.setStatus(0);

        // 创建 Calendar 实例，并设置为给定的时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(resMyToysVo.getExpireTime());

        // 在给定的时间上增加30天
        calendar.add(Calendar.DAY_OF_MONTH, 30);

        // 获取增加后的时间对象
        Date newDate = calendar.getTime();

        reqMyToysVo.setExpireTime(newDate);

        saveOrUpdate(reqMyToysVo);

        log.info("用户：{}，崽崽：{}，成功续费，有效期延长：30天", resGoodsOrdersVo.getUserId(), resGoodsOrdersVo.getMyToysId());
    }

    @Override
    public void handleExpireToys() {
        log.info("定时任务：【处理过期崽崽】------开始");
        int result = myToysMapper.updateMyToysExpire(new Date());
        log.info("定时任务：【处理过期崽崽】------结束，本次共处理：{}条", result);
    }

    @Override
    public void handleToysPower() {
        log.info("6点定时任务：【处理崽崽的体力、心情数据】------开始");


        String key = "dayMoodCount:";
        Set<String> keysList = redisUtils.getKeysByPrefix(key);
        redisUtils.batchDelByKeySet(keysList);



        int result = myToysMapper.updateMyToysPower();
        log.info("6点定时任务：【处理崽崽的体力、心情数据】------结束，本次共处理：{}条", result);
    }

    @Override
    public ResultT restorePower(ReqMyToysVo reqMyToysVo) {
        if (reqMyToysVo.getId() == null) {
            return ResultT.fail("崽崽id不能为空");
        }
        reqMyToysVo.setUserId(RequestHolder.getUserId());
        ResMyToysVo resMyToysVo = getResModelByConditions(reqMyToysVo);
        if (resMyToysVo == null) {
            return ResultT.fail("未查询到数据");
        }
        int power = resMyToysVo.getPower() + 10 ;
        if (power > 100) {
            power = 100;
        }
        resMyToysVo.setPower(power);
        updateModel(resMyToysVo);
        return ResultT.success();
    }


}
